package it.polimi.traveldream.ejb;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import it.polimi.traveldream.ejb.management.PackDTO;
import it.polimi.traveldream.ejb.management.PackMng;

import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class BeanPacchetto implements PackMng{
	@PersistenceContext
    private EntityManager em;
	
	@Resource
	private EJBContext context;
	
	private PackDTO selectedPack;
	

	@Override
	public void save(PackDTO pack) {
		Query query = em.createNamedQuery(Escursione.FINDBYID,Escursione.class);
		query.setParameter(1, pack.getEscursione());
		System.out.print("HERE0" + pack.getEscursione());
		Escursione esc = (Escursione) query.getResultList().get(0);
		System.out.print("HERE1" + pack.getHotel());
		Query query1 = em.createNamedQuery(Hotel.FINDID,Hotel.class);
		query1.setParameter(1, pack.getHotel());
		Hotel hotel = (Hotel) query1.getResultList().get(0);
		System.out.print("HERE2");
		Query query2 = em.createNamedQuery(Volo.FINDID,Volo.class);
		query2.setParameter(1, pack.getVoloAndata());
		Volo voloand = (Volo) query2.getResultList().get(0);
		query2.setParameter(1, pack.getVoloRitorno());
		Volo volorit = (Volo) query2.getResultList().get(0);
		System.out.print("HERE3");
		Pacchetti pacch = new Pacchetti(pack,hotel,voloand,volorit,esc);
		em.persist(pacch);
		
		
	}

	@Override
	public void update(PackDTO pack) {
		Query quer = em.createNamedQuery(Pacchetti.FINDBYID);
		quer.setParameter(1, pack.getId());
		Pacchetti pacch = (Pacchetti) quer.getResultList().get(0);
		Query query = em.createNamedQuery(Escursione.FINDBYID,Escursione.class);
		query.setParameter(1, pack.getEscursione());
		Escursione esc = (Escursione) query.getResultList().get(0);
		pacch.setEscursioneBean(esc);
		Query query1 = em.createNamedQuery(Hotel.FINDID,Hotel.class);
		query1.setParameter(1, pack.getHotel());
		Hotel hotel = (Hotel) query1.getResultList().get(0);
		pacch.setHotelBean(hotel);
		Query query2 = em.createNamedQuery(Volo.FINDID,Volo.class);
		query2.setParameter(1, pack.getVoloAndata());
		Volo voloand = (Volo) query2.getResultList().get(0);
		query2.setParameter(1, pack.getVoloRitorno());
		Volo volorit = (Volo) query2.getResultList().get(0);
		pacch.setVolo1(voloand);
		pacch.setVolo2(volorit);
		Query upd = em.createNamedQuery(Pacchetti.UPDPACC);
		upd.setParameter("nome", pack.getNome());
		upd.setParameter("id", pack.getId());
		upd.setParameter("dataPartenza", pack.getDataPartenza());
		upd.setParameter("dataArrivo", pack.getDataArrivo());
		upd.setParameter("voloA", voloand);
		upd.setParameter("voloR", volorit);
		upd.setParameter("hotel", hotel);
		upd.setParameter("escursione", esc);
		upd.setParameter("citta", pack.getLuogo());
		upd.setParameter("prezzo", pack.getPrezzo());
		upd.setParameter("numPosti", pack.getNumeroPosti());
		upd.executeUpdate();
		
		
	}

	@Override
	public PackDTO getPackDTO() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<PackDTO> searchByName(String value) {
		List<Pacchetti> pacch = em.createNamedQuery(Pacchetti.FIND_NAME,Pacchetti.class).setParameter("nome", value).getResultList();
		return convertToDTO(pacch);
	}

	@Override
	public List<PackDTO> searchByDate(Date start, Date end) {
		// TODO Auto-generated method stub
		return null;
	}
	
	private List<PackDTO> convertToDTO (List<Pacchetti> pacchettiDaConv) {
		List<PackDTO> returnedItems=new ArrayList<PackDTO>();
		Iterator<Pacchetti> iter=pacchettiDaConv.iterator();
		while(iter.hasNext()){
			returnedItems.add(convertToDTO(iter.next()));
		}
		return returnedItems;
	}
	
	private PackDTO convertToDTO (Pacchetti pacchetto) {
		PackDTO result = new PackDTO();
		result.setNome(pacchetto.getNome());
		result.setDataPartenza(pacchetto.getDataPartenza());
		result.setDataArrivo(pacchetto.getDataArrivo());
		result.setEscursione(pacchetto.getEscursioneBean().getIdEscursione());
		result.setHotel(pacchetto.getHotelBean().getIdHotel());
		result.setNumeroPosti(pacchetto.getNumeroPosti());
		result.setPrezzo(pacchetto.getPrezzoTotale());
		result.setLuogo(pacchetto.getCitta());
		result.setVoloAndata(pacchetto.getVolo1().getIdVolo());
		result.setVoloRitorno(pacchetto.getVolo2().getIdVolo());
		result.setId(pacchetto.getIdPacchetti());
		
		return result ;
	}
	
	
	 
	public List<PackDTO> getListaPacchetti(){
		List<Pacchetti> packs = em.createNamedQuery(Pacchetti.FIND_ALL,Pacchetti.class).getResultList();
		List<PackDTO> list=convertToDTO(packs);
		return list;
		
	}
	public PackDTO getSelectedPack(){
		return selectedPack;  
	}
	

	@Override
	@RolesAllowed(Gruppo._IMPIEGATO)
	public void delete(PackDTO pack) {
		Query query = em.createNamedQuery(Pacchetti.DELETE);
		query.setParameter(1, pack.getId());
		query.executeUpdate();
		
	}
	
	public List<PackDTO> searchCitta(String parola){
		Query query = em.createNamedQuery(Pacchetti.FINDBYCITY, Pacchetti.class);
		query.setParameter(1, parola);
		List<Pacchetti> packs=castList(Pacchetti.class,query.getResultList());
		List<PackDTO> list=convertToDTO(packs);
		return list;
		
	}
	
	private static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
	    List<T> r = new ArrayList<T>(c.size());
	    for(Object o: c)
	      r.add(clazz.cast(o));
	    return r;
	}

	@Override
	public List<PackDTO> searchNome(String nome) {
		Query query = em.createNamedQuery(Pacchetti.FIND_NAME, Pacchetti.class);
		query.setParameter(1, nome);
		List<Pacchetti> packs=castList(Pacchetti.class,query.getResultList());
		List<PackDTO> list=convertToDTO(packs);
		return list;
	}

	@Override
	public PackDTO searchById(int id) {
		Query query = em.createNamedQuery(Pacchetti.FINDBYID, Pacchetti.class);
		query.setParameter(1, id);
		Pacchetti pacch = (Pacchetti) query.getResultList().get(0);
		return convertToDTO(pacch);
	}
	
	public List<PackDTO> listaPaccDisp() {
		List<Pacchetti> list =em.createNamedQuery(Pacchetti.DISP,Pacchetti.class).getResultList();
		List<PackDTO> listRet= new ArrayList<PackDTO>();
		for (Pacchetti p :list) {
			listRet.add(convertToDTO(p));
		}
		return listRet;
	}
	
	public List<PackDTO> searchCittaDisp(String citta) {
		Query query = em.createNamedQuery(Pacchetti.DISP,Pacchetti.class);
		query.setParameter(1, citta);
		List<Pacchetti> list =castList(Pacchetti.class,query.getResultList());
		List<PackDTO> listRet= new ArrayList<PackDTO>();
		for (Pacchetti p :list) {
			listRet.add(convertToDTO(p));
		}
		return listRet;
	}
	
}
